package main

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

// getServiceEndpoints获取指定Service的Endpoint IP列表
func getServiceEndpoints(clientset *kubernetes.Clientset, serviceName, namespace string) ([]string, error) {
	endpoints, err := clientset.CoreV1().Endpoints(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
	if err != nil {
		return nil, err
	}
	var ips []string
	for _, subset := range endpoints.Subsets {
		for _, address := range subset.Addresses {
			ips = append(ips, address.IP)
		}
	}
	return ips, nil
}

// updateNginxConfig根据给定的Endpoint IP列表更新Nginx配置文件中的upstream配置块
func updateNginxConfig(endpoints []string, nginxConfPath string) error {
	upstreamConfig := "    upstream pushgateway {\n        ip_hash;\n"
	for _, ip := range endpoints {
		upstreamConfig += fmt.Sprintf("        server %s;\n", ip)
	}
	upstreamConfig += "    }\n"

	data, err := os.ReadFile(nginxConfPath)
	if err != nil {
		return err
	}
	lines := string(data)
	startIndex := -1
	endIndex := -1
	for i, line := range strings.Split(lines, "\n") {
		if strings.Trim(line, " ") == "upstream pushgateway {" {
			startIndex = i
		}
		if strings.Trim(line, " ") == "}" {
			if startIndex != -1 {
				endIndex = i
				break
			}
		}
	}
	if startIndex == -1 || endIndex == -1 {
		return fmt.Errorf("could not find upstream block in nginx config")
	}
	before := strings.Split(lines, "\n")[:startIndex]
	after := strings.Split(lines, "\n")[endIndex+1:]
	updatedLines := strings.Join(append(before, upstreamConfig), "\n") + strings.Join(after, "\n")
	return os.WriteFile(nginxConfPath, []byte(updatedLines), 0644)
}

func main() {
	// 加载Kubernetes集群内配置
	config, err := rest.InClusterConfig()
	if err != nil {
		panic(err.Error())
	}
	// 创建Kubernetes客户端集
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err.Error())
	}
	// 假设Nginx配置文件路径，可根据实际情况修改
	nginxConfPath := "/etc/nginx/nginx.conf"
	// 假设Service名称和命名空间，按需替换
	serviceName := "push-gateway-prometheus-pushgateway"
	namespace := "monitor"
	for {
		endpoints, err := getServiceEndpoints(clientset, serviceName, namespace)
		if err != nil {
			fmt.Printf("Error getting endpoints: %v\n", err)
			continue
		}
		err = updateNginxConfig(endpoints, nginxConfPath)
		if err != nil {
			fmt.Printf("Error updating nginx config: %v\n", err)
			continue
		}
		// 执行Nginx -s reload命令重新加载配置
		cmd := exec.Command("nginx", "-s", "reload")
		err = cmd.Run()
		if err != nil {
			fmt.Printf("Error reloading nginx: %v\n", err)
			continue
		}
		time.Sleep(5 * time.Second)
	}
}
